// Package ioc
/**
* @Project : geektime-basic-go-study
* @File    : sms.go
* @IDE     : GoLand
* @Author  : Tvux
* @Date    : 2024/10/7 22:33
**/

package ioc

import (
	"geektime-basic-go-study/webook/backend/internal/repository"
	"geektime-basic-go-study/webook/backend/internal/service"
	"geektime-basic-go-study/webook/backend/internal/service/sms"
	"geektime-basic-go-study/webook/backend/internal/service/sms/aliyun"
	"geektime-basic-go-study/webook/backend/internal/service/sms/auth"
	"geektime-basic-go-study/webook/backend/internal/service/sms/failover"
	"geektime-basic-go-study/webook/backend/internal/service/sms/huawei"
	"geektime-basic-go-study/webook/backend/internal/service/sms/local"
	"geektime-basic-go-study/webook/backend/internal/service/sms/ratelimit"
	"geektime-basic-go-study/webook/backend/internal/service/sms/tencent"
	"github.com/HJH0924/GenericGo/ratelimiter"
	"github.com/redis/go-redis/v9"
	"github.com/spf13/viper"
	"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common"
	"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/profile"
	"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/regions"
	tencentSMS "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/sms/v20210111"
	"os"
	"time"
)

func InitLocalSMSService() sms.Service {
	return local.NewService()
}

func InitTencentSMSService() sms.Service {
	// 硬编码密钥到代码中有可能随代码泄露而暴露，有安全隐患，并不推荐。
	// 为了保护密钥安全，建议将密钥设置在环境变量中或者配置文件中，请参考本文凭证管理章节。
	credential := common.NewCredential(
		os.Getenv("TENCENTCLOUD_SECRET_ID"),
		os.Getenv("TENCENTCLOUD_SECRET_KEY"),
	)
	client, _ := tencentSMS.NewClient(credential, regions.Guangzhou, profile.NewClientProfile())

	return tencent.NewService(client, "YOUR_SMS_SDK_APP_ID", "YOUR_SIGN_NAME")
}

func InitAliyunSMSService() sms.Service {
	return aliyun.NewService()
}

func InitHuaweiSMSService() sms.Service {
	return huawei.NewService()
}

func GetSMSServices() []sms.Service {
	return []sms.Service{
		InitLocalSMSService(),
		InitAliyunSMSService(),
		InitHuaweiSMSService(),
	}
}

func InitAuthSMSService(svcs []sms.Service) {
	for i := range svcs {
		svcs[i] = auth.NewSMSAuthService(svcs[i], []byte(viper.GetString("config.authConf.secretKey")))
	}
}

func InitRateLimitSMSService(redisClient redis.Cmdable, svcs []sms.Service) {
	for i := range svcs {
		svcs[i] = ratelimit.NewSMSRateLimitService(svcs[i], ratelimiter.NewRedisRateLimiter(redisClient, time.Second, 3000))
	}
}

func InitFailoverSMSService(svcs []sms.Service) sms.Service {
	return failover.NewSMSFailoverService(svcs...)
}

func InitSMSService(redisClient redis.Cmdable, svcs []sms.Service) sms.Service {
	// 装饰器模式
	// 核心实现：svcs 可以增加/更换为别的核心实现，比如腾讯
	// 新增功能
	// 接口鉴权
	InitAuthSMSService(svcs)
	// 限流
	InitRateLimitSMSService(redisClient, svcs)
	// failover
	return InitFailoverSMSService(svcs)
	// ...继续增加别的新功能装饰实现
}

func InitSMSCodeService(repo repository.CodeRepository, smsService sms.Service) service.CodeService {
	return service.NewSMSCodeService(repo, smsService, 30*time.Minute)
}
